﻿using System;
using System.Text;

namespace System.Data
{
    /// <summary>
    /// DbProviderFactory
    /// </summary>
    public class DbProviderFactory : System.Data.Common.DbProviderFactory
    {
        /// <summary>
        /// 获取数据库类型
        /// </summary>
        public DatabaseType DatabaseType { get; protected set; }

        /// <summary>
        /// 
        /// </summary>
        private DbProviderFactory() { }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbType"></param>
        public DbProviderFactory(DatabaseType dbType) { this.DatabaseType = dbType; }

        /// <summary>
        /// 创建命令对象
        /// </summary>
        /// <returns></returns>
        public new IDbCommand CreateCommand()
        {
            IDbCommand command = null;
            switch (this.DatabaseType)
            {
                case DatabaseType.Odbc:
                    command = new Odbc.OdbcCommand();
                    break;
                case DatabaseType.Oledb:
                    command = new OleDb.OleDbCommand();
                    break;
                case DatabaseType.Access:
                    command = new OleDb.OleDbCommand();
                    break;
                case DatabaseType.SQLite:
                    //  TODO:SQLite
                    break;
                case DatabaseType.MySQL:
                    //  TODO:MySql
                    break;
                case DatabaseType.SQLServer:
                    command = new SqlClient.SqlCommand();
                    break;
                case DatabaseType.SqlServerCe:
                    //command = new SqlServerCe.SqlCeCommand();
                    break;
                case DatabaseType.Oracle:
                    command = new OracleClient.OracleCommand();
                    break;
                default:
                    break;
            }
            return command;
        }

        /// <summary>
        /// 创建连接对象
        /// </summary>
        /// <returns></returns>
        public new IDbConnection CreateConnection()
        {
            IDbConnection connection = null;
            switch (this.DatabaseType)
            {
                case DatabaseType.Odbc:
                    connection = new Odbc.OdbcConnection();
                    break;
                case DatabaseType.Oledb:
                    connection = new OleDb.OleDbConnection();
                    break;
                case DatabaseType.Access:
                    connection = new OleDb.OleDbConnection();
                    break;
                case DatabaseType.SQLite:
                    //  TODO:SQLite
                    break;
                case DatabaseType.MySQL:
                    //  TODO:MySql
                    break;
                case DatabaseType.SQLServer:
                    connection = new SqlClient.SqlConnection();
                    break;
                case DatabaseType.SqlServerCe:
                    //connection = new SqlServerCe.SqlCeConnection();
                    break;
                case DatabaseType.Oracle:
                    connection = new OracleClient.OracleConnection();
                    break;
                default:
                    break;
            }
            return connection;
        }

        /// <summary>
        /// 创建数据填充对象
        /// </summary>
        /// <returns></returns>
        public new System.Data.Common.DbDataAdapter CreateDataAdapter()
        {
            System.Data.Common.DbDataAdapter dataAdapter = null;
            switch (this.DatabaseType)
            {
                case DatabaseType.Odbc:
                    dataAdapter = new Odbc.OdbcDataAdapter();
                    break;
                case DatabaseType.Oledb:
                    dataAdapter = new OleDb.OleDbDataAdapter();
                    break;
                case DatabaseType.Access:
                    dataAdapter = new OleDb.OleDbDataAdapter();
                    break;
                case DatabaseType.SQLite:
                    //  TODO:SQLite
                    break;
                case DatabaseType.MySQL:
                    //  TODO:MySql
                    break;
                case DatabaseType.SQLServer:
                    dataAdapter = new SqlClient.SqlDataAdapter();
                    break;
                case DatabaseType.SqlServerCe:
                    //dataAdapter = new SqlServerCe.SqlCeDataAdapter();
                    break;
                case DatabaseType.Oracle:
                    dataAdapter = new OracleClient.OracleDataAdapter();
                    break;
                default:
                    break;
            }
            return dataAdapter;
        }

        /// <summary>
        /// 创建命令参数对象
        /// </summary>
        /// <returns></returns>
        public new IDataParameter CreateParameter()
        {
            return this.CreateParameter(null, null);
        }

        /// <summary>
        /// 创建命令参数对象
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public IDataParameter CreateParameter(string name, object value)
        {
            IDataParameter parameter = null;
            switch (this.DatabaseType)
            {
                case DatabaseType.Odbc:
                    parameter = string.IsNullOrEmpty(name) ? new Odbc.OdbcParameter() : new Odbc.OdbcParameter(name, value);
                    break;
                case DatabaseType.Oledb:
                    parameter = string.IsNullOrEmpty(name) ? new OleDb.OleDbParameter() : new OleDb.OleDbParameter(name, value);
                    break;
                case DatabaseType.Access:
                    parameter = string.IsNullOrEmpty(name) ? new OleDb.OleDbParameter() : new OleDb.OleDbParameter(name, value);
                    break;
                case DatabaseType.SQLite:
                    //  TODO:SQLite
                    break;
                case DatabaseType.MySQL:
                    //  TODO:MySql
                    break;
                case DatabaseType.SQLServer:
                    parameter = string.IsNullOrEmpty(name) ? new SqlClient.SqlParameter() : new SqlClient.SqlParameter(name, value);
                    break;
                case DatabaseType.SqlServerCe:
                    //parameter = string.IsNullOrEmpty(name) ? new SqlServerCe.SqlCeParameter() : new SqlServerCe.SqlCeParameter(name, value);
                    break;
                case DatabaseType.Oracle:
                    parameter = string.IsNullOrEmpty(name) ? new OracleClient.OracleParameter() : new OracleClient.OracleParameter(name, value);
                    break;
                default:
                    break;
            }
            return parameter;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override Common.DbCommandBuilder CreateCommandBuilder()
        {
            Common.DbCommandBuilder commandBuilder = null;
            switch (this.DatabaseType)
            {
                case DatabaseType.Odbc:
                    commandBuilder = new Odbc.OdbcCommandBuilder();
                    break;
                case DatabaseType.Oledb:
                    commandBuilder = new OleDb.OleDbCommandBuilder();
                    break;
                case DatabaseType.Access:
                    commandBuilder = new OleDb.OleDbCommandBuilder();
                    break;
                case DatabaseType.SQLite:
                    //  TODO:SQLite
                    break;
                case DatabaseType.MySQL:
                    //  TODO:MySql
                    break;
                case DatabaseType.SQLServer:
                    commandBuilder = new SqlClient.SqlCommandBuilder();
                    break;
                case DatabaseType.SqlServerCe:
                    //commandBuilder = new SqlServerCe.SqlCeCommandBuilder();
                    break;
                case DatabaseType.Oracle:
                    commandBuilder = new OracleClient.OracleCommandBuilder();
                    break;
                default:
                    break;
            }
            return commandBuilder;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override Common.DbConnectionStringBuilder CreateConnectionStringBuilder()
        {
            Common.DbConnectionStringBuilder conStrBuilder = null;
            switch (this.DatabaseType)
            {
                case DatabaseType.Odbc:
                    conStrBuilder = new Odbc.OdbcConnectionStringBuilder();
                    break;
                case DatabaseType.Oledb:
                    conStrBuilder = new OleDb.OleDbConnectionStringBuilder();
                    break;
                case DatabaseType.Access:
                    conStrBuilder = new OleDb.OleDbConnectionStringBuilder();
                    break;
                case DatabaseType.SQLite:
                    //  TODO:SQLite
                    break;
                case DatabaseType.MySQL:
                    //  TODO:MySql
                    break;
                case DatabaseType.SQLServer:
                    conStrBuilder = new SqlClient.SqlConnectionStringBuilder();
                    break;
                case DatabaseType.SqlServerCe:
                    conStrBuilder = null;
                    break;
                case DatabaseType.Oracle:
                    conStrBuilder = new OracleClient.OracleConnectionStringBuilder();
                    break;
                default:
                    break;
            }
            return conStrBuilder;
        }

        /// <summary>
        /// 验证参数
        /// </summary>
        /// <param name="parameter"></param>
        public void ValidParameter(IDataParameter parameter)
        {
            if (parameter != null)
            {
                #region 验证名称

                if (parameter.ParameterName != null)
                {
                    switch (this.DatabaseType)
                    {
                        case DatabaseType.Odbc:
                            break;
                        case DatabaseType.Oledb:
                            break;
                        case DatabaseType.Access:
                            parameter.ParameterName = "?";
                            break;
                        case DatabaseType.SQLite:
                            break;
                        case DatabaseType.MySQL:
                            break;
                        case DatabaseType.SQLServer:
                            if (parameter.ParameterName.Length > 0 && parameter.ParameterName[0] != '@')
                                parameter.ParameterName = string.Format("{0}{1}", '@', parameter.ParameterName);
                            break;
                        case DatabaseType.SqlServerCe:
                            if (parameter.ParameterName.Length > 0 && parameter.ParameterName[0] != '@')
                                parameter.ParameterName = string.Format("{0}{1}", '@', parameter.ParameterName);
                            break;
                        case DatabaseType.Oracle:
                            if (parameter.ParameterName.Length > 0 && parameter.ParameterName[0] != ':')
                                parameter.ParameterName = string.Format("{0}{1}", ':', parameter.ParameterName);
                            break;
                        default:
                            break;
                    }
                }

                #endregion

                #region 验证值

                if (parameter.Value == null)
                    parameter.Value = DBNull.Value;

                #endregion

                #region 验证值类型

                if (parameter.Value.GetType() == typeof(byte[]))
                    parameter.DbType = DbType.Binary;

                #endregion

            }
        }

        #region ParamPrefix

        private string _paramPrefix = null;
        /// <summary>
        /// 获取或设置参数前缀
        /// </summary>
        public string ParamPrefix
        {
            get
            {
                if (this._paramPrefix == null)
                {
                    switch (this.DatabaseType)
                    {
                        case DatabaseType.Odbc:
                            break;
                        case DatabaseType.Oledb:
                            break;
                        case DatabaseType.Access:
                            this._paramPrefix = "?";
                            break;
                        case DatabaseType.SQLite:
                            this._paramPrefix = "?";
                            break;
                        case DatabaseType.MySQL:
                            this._paramPrefix = "?";
                            break;
                        case DatabaseType.SQLServer:
                            this._paramPrefix = "@";
                            break;
                        case DatabaseType.SqlServerCe:
                            this._paramPrefix = "@";
                            break;
                        case DatabaseType.Oracle:
                            this._paramPrefix = ":";
                            break;
                        default:
                            break;
                    }
                }
                return this._paramPrefix;
            }
            set { this._paramPrefix = value; }
        }

        #endregion
    }
}
